import time

# 起始时间戳（毫秒）
START_TIMESTAMP = 1609459200000  # 2021-01-01 00:00:00 UTC

# 位移量和掩码
GEO_CODE_SHIFT = 56  # 8（序列号）+ 7（对象类型）+ 7（地域编码）
TYPE_CODE_SHIFT = 49  # 8（序列号）+ 7（对象类型）
SEQUENCE_SHIFT = 8  # 8（序列号）
SEQUENCE_MASK = (1 << 8) - 1  # 8位序列号的最大值
TYPE_CODE_MASK = (1 << 7) - 1  # 7位对象类型的最大值
GEO_CODE_MASK = (1 << 7) - 1  # 7位地域编码的最大值


class GeoTypeIdGenerator:
    def __init__(self, geo_code, type_code):
        if geo_code > GEO_CODE_MASK:
            raise ValueError(f"GeoCode cannot exceed {GEO_CODE_MASK}")
        if type_code > TYPE_CODE_MASK:
            raise ValueError(f"TypeCode cannot exceed {TYPE_CODE_MASK}")
        self.geo_code = geo_code
        self.type_code = type_code
        self.sequence = 0
        self.last_timestamp = -1

    def _get_current_timestamp(self):
        return int(time.time() * 1000)

    def generate_id(self):
        current_timestamp = self._get_current_timestamp()

        if current_timestamp == self.last_timestamp:
            self.sequence += 1
            if self.sequence > SEQUENCE_MASK:
                while current_timestamp == self.last_timestamp:
                    current_timestamp = self._get_current_timestamp()
                self.sequence = 0
        else:
            self.sequence = 0
            self.last_timestamp = current_timestamp

        id_ = (current_timestamp << GEO_CODE_SHIFT) | \
              (self.geo_code << TYPE_CODE_SHIFT) | \
              (self.type_code << SEQUENCE_SHIFT) | \
              self.sequence

        return id_

    @staticmethod
    def print_id_details(id_):
        # 提取时间戳
        timestamp = (id_ >> GEO_CODE_SHIFT) + START_TIMESTAMP
        seconds, milliseconds = divmod(timestamp, 1000)  # 分离秒和毫秒
        date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(seconds / 1000))
        timestamp_str = f"{date}.{milliseconds:03d}"  # 格式化为 YYYY-MM-DD HH:MM:SS.sss

        # 提取地域编码
        geo_code = (id_ >> TYPE_CODE_SHIFT) & GEO_CODE_MASK

        # 提取对象类型
        type_code = (id_ >> SEQUENCE_SHIFT) & TYPE_CODE_MASK

        # 提取序列号
        sequence = id_ & SEQUENCE_MASK

        # 打印信息
        print(f"ID: {id_}")
        print(f"Timestamp: {timestamp_str}")
        print(f"Geo Code: {geo_code}")
        print(f"Type Code: {type_code}")
        print(f"Sequence: {sequence}")


if __name__ == "__main__":
    # 创建一个基于地域和对象类型的ID生成器
    generator = GeoTypeIdGenerator(geo_code=1, type_code=1)

    # 生成多个ID测试
    for _ in range(10):
        id_ = generator.generate_id()
        print(f"Generated ID: {id_}")
        GeoTypeIdGenerator.print_id_details(id_)
        print("----------------------------")
